
import {
    PerspectiveCamera, Scene, Vector3, WebGLRenderer, Object3D, Raycaster, Vector2, MOUSE
} from 'three'
import Stats from 'three/examples/jsm/libs/stats.module'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { TransformControls } from 'three/examples/jsm/controls/TransformControls'

export class TEngine {
    private dom: HTMLElement
    private renderer: WebGLRenderer
    private scene: Scene
    private camera: PerspectiveCamera
    private transformControls: TransformControls

    constructor(dom: HTMLElement) {
        this.dom = dom
        this.renderer = new WebGLRenderer({
            antialias: true
        })
        this.renderer.shadowMap.enabled = true
        // ，设为true允许改变canvas画面
        this.renderer.setSize(dom.offsetWidth, dom.offsetHeight, true)
        this.scene = new Scene()
        this.camera = new PerspectiveCamera(45, dom.offsetWidth / dom.offsetHeight, 1, 1000)

        this.camera.position.set(20, 20, 20)
        this.camera.lookAt(new Vector3(0, 0, 0))
        this.camera.up = new Vector3(0, 1, 0)

        // 初始性能监视器
        const stats = Stats()
        const statsDom = stats.domElement
        statsDom.style.position = 'fixed'
        statsDom.style.top = '0'
        statsDom.style.right = '5px'
        statsDom.style.left = 'unset'

        // 初始变换控制器
        let transing = false
        this.transformControls = new TransformControls(this.camera, this.renderer.domElement)
        this.transformControls.addEventListener('mouseDown',()=>{
            transing = true
        })
        this.scene.add(this.transformControls)
        // 变换控制器必须依附于一个物体
        // const target = new Object3D()
        // this.transformControls.attach(target)
        // this.scene.add(target)
        // 初始射线发射器
        const raycaster = new Raycaster()
        // 给renderer的canvas对象添加鼠标事件
        const mouse = new Vector2()
        let x = 0
        let y = 0
        let width = 0
        let height = 0
        this.renderer.domElement.addEventListener('mousemove', (event) => {
            x = event.offsetX
            y = event.offsetY
            width = this.renderer.domElement.offsetWidth
            height = this.renderer.domElement.offsetHeight
            mouse.x = x / width * 2 - 1
            mouse.y = -y * 2 / height + 1
        })
        this.renderer.domElement.addEventListener('click', event => {
            if(transing){
                transing = false
                return;
            }
            // 1 不要选择到变换控制器，它也是一个物体，透明看不见的。可以先消失，然后出现
            this.scene.remove(this.transformControls)

            raycaster.setFromCamera(mouse, this.camera)
            // fasle。是否只选择第一层物体
            const intersection = raycaster.intersectObjects(this.scene.children,false)

            // 2 已经正确选择到物体之后，要将变换控制器添加回来
            this.scene.add(this.transformControls)
            if (intersection.length) {
                const object = intersection[0].object
                console.log( intersection[0].object);
                
                this.transformControls.attach(object)
            }
        })

        // 初始orbitControls
        const orbitControls: OrbitControls = new OrbitControls(this.camera, this.renderer.domElement)
        // orbitControls.autoRotate = true
        orbitControls.mouseButtons = {
            LEFT: null as unknown as MOUSE,
            MIDDLE: MOUSE.DOLLY,
            RIGHT:MOUSE.ROTATE
        }

        const renderFun = () => {
            orbitControls.update()
            this.renderer.render(this.scene, this.camera)

            stats.update()
            requestAnimationFrame(renderFun)
        }
        renderFun()
        dom.append(this.renderer.domElement)
        dom.appendChild(statsDom)
    }
    addObject(...objects: Object3D[]) {
        objects.forEach((item: Object3D) => {
            this.scene.add(item)
        })
    }
}